package cn.mw.cmdb.template.strategy;

import cn.mw.cmdb.exception.ZabbixResultException;
import cn.mw.cmdb.service.AssetsManageService;
import cn.mw.cmdb.template.constant.MwTemplateConfigurationConstant;
import cn.mw.cmdb.template.entity.convert.MwTemplateConvertOne;
import cn.mw.cmdb.template.enums.TemplateDetailEnum;
import cn.mw.cmdb.template.enums.TriggerFunctionsDto;
import cn.mw.cmdb.template.param.MonitorItemParam;
import cn.mw.cmdb.template.param.MwTemplateConfigurationParam;
import cn.mw.cmdb.template.param.TriggerParam;
import cn.mw.main.api.common.ZabbixDubboService;
import cn.mw.microMonitorCommon.api.common.MwTPServerService;
import cn.mw.microMonitorCommon.api.opsengine.OpsengineApi;
import cn.mw.microMonitorCommon.constants.ZabbixApiConstants;
import cn.mw.microMonitorCommon.constants.ZabbixMethodConstants;
import cn.mw.microMonitorCommon.entity.zabbix.MWZabbixAPIResult;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @description 策略抽象类
 */
public abstract class TemplateDetailHandler {

    @DubboReference(check = false, timeout = 120000)
    public ZabbixDubboService zabbixDubboService;

    @DubboReference(check = false, timeout = 120000)
    public OpsengineApi opsengineApi;

    @Value("${yunzhihui.destinationPath}")
    public String destinationPath;
    @Value("${yunzhihui.open}")
    public Boolean open;

    @Value("${yunzhihui.workflowId}")
    public String workflowId;

    @Value("${yunzhihui.url}")
    public String url;
    @Value("${yunzhihui.sendUrl}")
    public String sendUrl;

    @Value("${yunzhihui.workOrderId}")
    public String workOrderId;

    @Value("${yunzhihui.menuId}")
    public String menuId;

    @Value("${yunzhihui.accountId}")
    public String accountId;

    @Value("${yunzhihui.userid}")
    public String userid;

    @Value("${yunzhihui.type}")
    public String fileType;

    @DubboReference(check = false, timeout = 12000, mock = "true")
    public MwTPServerService tpServerService;

    public final String ZABBIX_V5 = "5.0";
    public final String ZABBIX_V6 = "6.0";

    public final String TRIGGER_ID = "triggerid";

    public final String description = "description";
    public final String expression = "expression";
    public final String priority = "priority";

    public final String delay = "delay";
    public final String key_ = "key_";
    public final String history = "history";
    public final String trends = "trends";
    public final String type = "type";
    public final String status = "status";
    public final String VALUE_MAP_ID = "valuemapid";
    public final String discover = "discover";
    public final String OP_DATA = "opdata";
    public final String width = "width";
    public final String height = "height";
    public final String GRAPH_TYPE = "graphtype";

    public final String applicationId = "applicationid";
    public final String TEMPLATE_NAME = "host";
    public final String HOST_IDS = "hostids";


    public abstract TemplateDetailEnum handlerType();

    public abstract Object getData(MwTemplateConfigurationParam param);

    public abstract Object createData(MwTemplateConfigurationParam param);

    public abstract Object updateData(MwTemplateConfigurationParam param);

    public abstract Object deleteData(MwTemplateConfigurationParam param);

    public abstract Object selectDataById(MwTemplateConfigurationParam param);

//    public abstract List<Map> getExportData(MwTemplateConfigurationParam param);

    public void delMapNullValue(Map zabbixParam) {
        Iterator iterator = zabbixParam.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            if (entry.getValue() == null) {
                iterator.remove();
            } else if (entry.getValue() instanceof List) {
                List list = (List) entry.getValue();
                if (CollectionUtils.isEmpty(list)) {
                    iterator.remove();
                }
            }
        }
    }

    public Page pageHandler(List realDatas, Integer pageNum, Integer pageSize) {
        if (CollectionUtils.isNotEmpty(realDatas)) {
            int fromIndex = pageSize * (pageNum - 1);
            int toIndex = pageSize * pageNum;
            if (toIndex > realDatas.size()) {
                toIndex = realDatas.size();
            }
            List<Map<String, Object>> pageList = realDatas.subList(fromIndex, toIndex);
            Page page = new Page();
            page.setRecords(pageList);
            page.setTotal(realDatas.size());
            return page;
        }
        return new Page();
    }

    public void translateExpressionBatch(List<TriggerParam> triggerParams, MwTemplateConfigurationParam param, Integer type) {
        //获取itemid
        List<String> itemIds = new ArrayList<>();
        for (TriggerParam triggerParam : triggerParams) {
            List<TriggerFunctionsDto> functions = triggerParam.getFunctions();
            if (CollectionUtils.isEmpty(functions)) {
                continue;
            }
            itemIds.addAll(functions.stream().map(s -> s.getItemid()).collect(Collectors.toList()));
        }
        if (CollectionUtils.isEmpty(itemIds)) {
            return;
        }
        String templateName = getTemplateName(param);
        param.setTemplateName(templateName);
        //监控项的键值
        Map zabbixParam = new HashMap();
        zabbixParam.put(MwTemplateConfigurationConstant.ITEM_IDS, itemIds);
        zabbixParam.put(MwTemplateConfigurationConstant.OUTPUT, Arrays.asList(MwTemplateConfigurationConstant.ITEM_ID, key_, MwTemplateConfigurationConstant.NAME));
        MWZabbixAPIResult zabbixAPIResult = null;
        if (type == 1) {
            zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.ITEM_GET, zabbixParam);
        } else {
            zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.ITEM_PROTOTYPE_GET, zabbixParam);
        }
        if (zabbixAPIResult == null || zabbixAPIResult.isFail()) {
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
        List<MonitorItemParam> monitorItemParams = JSONArray.parseArray(String.valueOf(zabbixAPIResult.getData()), MonitorItemParam.class);
        if (CollectionUtils.isEmpty(monitorItemParams)) {
            return;
        }
        Map<String, String> itemMap = monitorItemParams.stream().collect(Collectors.toMap(s -> s.getItemid(), s -> s.getKey_(), (o1, o2) -> o1));
        for (TriggerParam triggerConvertDto : triggerParams) {
            String triggerExpression = triggerConvertDto.getExpression();
            String recoveryExpression = triggerConvertDto.getRecovery_expression();
            List<TriggerFunctionsDto> functions = triggerConvertDto.getFunctions();
            if (CollectionUtils.isEmpty(functions)) {
                continue;
            }
            for (TriggerFunctionsDto function : functions) {
                String functionId = function.getFunctionid();
                if (triggerExpression.contains(functionId)) {
                    String itemKey = itemMap.get(function.getItemid());
                    triggerExpression = assembleExpression(triggerExpression, param.getTemplateName(), itemKey, function);
                }
                if (StringUtils.isNotEmpty(recoveryExpression) && recoveryExpression.contains(functionId)) {
                    String itemKey = itemMap.get(function.getItemid());
                    recoveryExpression = assembleExpression(recoveryExpression, param.getTemplateName(), itemKey, function);
                }
            }
            triggerConvertDto.setExpression(triggerExpression);
            triggerConvertDto.setRecovery_expression(recoveryExpression);
        }
    }

    public String assembleExpression(String value, String templateName, String itemKey, TriggerFunctionsDto function) {
        return value.replace("{" + function.getFunctionid() + "}", function.getFunction() + "(/" + templateName + "/" + itemKey + function.getParameter().replace("$", "") + ")");
    }

    public String getTemplateName(MwTemplateConfigurationParam param) {
        Map zabbixParam = new HashMap();
        zabbixParam.put(MwTemplateConfigurationConstant.TEMPLATE_IDS, param.getTemplateId());
        zabbixParam.put(MwTemplateConfigurationConstant.OUTPUT, Arrays.asList(MwTemplateConfigurationConstant.TEMPLATE_ID, MwTemplateConfigurationConstant.NAME, MwTemplateConfigurationConstant.TEMPLATE_NAME));
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TEMPLATE_GET, zabbixParam);
        if (zabbixAPIResult == null && zabbixAPIResult.isFail()) {
            return null;
        }
        List<MwTemplateConvertOne> convertOnes = com.alibaba.fastjson.JSONArray.parseArray(String.valueOf(zabbixAPIResult.getData()), MwTemplateConvertOne.class);
        if (CollectionUtils.isEmpty(convertOnes)) {
            return null;
        }
        return convertOnes.get(0).getHost();
    }


    public String getHostName(MwTemplateConfigurationParam param) {
        Map zabbixParam = new HashMap();
        zabbixParam.put(HOST_IDS, param.getHostId());
        zabbixParam.put(MwTemplateConfigurationConstant.OUTPUT, Arrays.asList(MwTemplateConfigurationConstant.TEMPLATE_NAME, MwTemplateConfigurationConstant.HOST_ID, MwTemplateConfigurationConstant.NAME));
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.HOST_GET, zabbixParam);
        if (zabbixAPIResult == null && zabbixAPIResult.isFail()) {
            return null;
        }
        List<MwTemplateConvertOne> convertOnes = com.alibaba.fastjson.JSONArray.parseArray(String.valueOf(zabbixAPIResult.getData()), MwTemplateConvertOne.class);
        if (CollectionUtils.isEmpty(convertOnes)) {
            return null;
        }
        return convertOnes.get(0).getHost();
    }
}
